package com.echovin.esb.gateway.parameter.impl;

import com.echovin.esb.gateway.locator.GatewayParameterValidateResourceLocator;
import com.echovin.esb.gateway.model.TwoTuple;
import com.echovin.esb.gateway.parameter.SchemaValidator;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jackson.JsonLoader;
import com.github.fge.jsonschema.core.report.LogLevel;
import com.github.fge.jsonschema.core.report.ProcessingMessage;
import com.github.fge.jsonschema.core.report.ProcessingReport;
import com.github.fge.jsonschema.main.JsonSchema;
import com.github.fge.jsonschema.main.JsonSchemaFactory;
import lombok.extern.slf4j.Slf4j;

import java.util.Iterator;

@Slf4j
public class JsonSchemaValidator implements SchemaValidator {
    private final static JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
    private GatewayParameterValidateResourceLocator validateResourceLocator;

    public JsonSchemaValidator(GatewayParameterValidateResourceLocator validateResourceLocator) {
        this.validateResourceLocator = validateResourceLocator;
    }

    @Override
    public TwoTuple<Boolean, String> schemaValidator(String requestPath, String bodyStr) {
        Boolean result = false;
        String message = null;
        try {
            // 从数据库查询schema
            String schemaStr = validateResourceLocator.getSchema(requestPath);
            JsonNode mainNode = JsonLoader.fromString(schemaStr);
            JsonNode instanceNode = JsonLoader.fromString(bodyStr);
            JsonSchema schema = null;
            ProcessingReport processingReport = null;
            schema = factory.getJsonSchema(mainNode);
            processingReport = schema.validate(instanceNode);

            if (processingReport.isSuccess()) {
                result = true;
            } else {
                Iterator<ProcessingMessage> it = processingReport.iterator();
                while(it.hasNext()){
                    ProcessingMessage processingMessage = it.next();
                    if (processingMessage.getLogLevel() == LogLevel.ERROR) {
                        message = processingMessage.getMessage();
                        log.error("JSON文件通过Schema文件校验失败:{}", processingMessage.getMessage());
                        break;
                    }
                }
            }
        } catch (Exception e) {
            message = e.getMessage();
            log.error("JSON文件通过Schema文件校验失败:{}", e.getMessage());
        }

        return new TwoTuple(result, message);
    }
}
